package ltd.ninefish.framework.redis.configure;

import jakarta.annotation.Resource;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author zhaoxiubin
 * create-time 2024-01-13 21:35
 * description redis配置
 **/
@Configuration
@EnableCaching
// @Configuration：该注解标志这是一个配置类，「自动配置类可以不加该注解」。
// @EnableConfigurationProperties：这个配置也是经常使用了，使得指定的属性配置生效。
//      一般自动配置类都需要从全局属性配置中读取自定义的配置，这就是一个开关。
// @ConditionalOnXxxx：该注解是自动配置类的核心了，自动配置类既要启动时自动配置，
//      又要保证用户用户自定义的配置覆盖掉自动配置，该注解就是一个条件语句，只有当指定条件成立才会执行某操作。
// @AutoConfigureAfter：当前配置类在指定配置类之后执行
// @AutoConfigureBefore：当前配置类在指定配置类之前执行
// @AutoConfigureOrder：指定优先级，数值越小，优先级越高.
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfig implements CachingConfigurer
{
    @Resource
    private RedisConnectionFactory connectionFactory;

    @Bean
    @SuppressWarnings(value = { "unchecked", "rawtypes" })
    public RedisTemplate<Object, Object> redisTemplate()
    {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
}
